﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Meta.Numerics.Matrices;
using System.Data.SQLite;

namespace Regression1
{
    public class regression
    {
        
                        public static void runquery(string querytext)
                        {
                        SQLiteConnection conn = new SQLiteConnection("data source=" + "C:\\Mosaic\\Coefficients");
                        try
                        {

                        conn.Open();

                        }

                        catch (Exception)
                        {

                        Console.WriteLine("not open");
                        }
                        SQLiteCommand cmd = new SQLiteCommand(conn);
                        cmd.CommandText = querytext;
                        cmd.ExecuteNonQuery();
                        conn.Close();
                        }

                        //main part of the class
                    //  public  static void MainR(s)
                      public static void regressioncontrol (int nvalues, double[,] values, string modelname)
                        {

                        /*int fvalues = 5;
                        double[,] fakevalue = new double[fvalues, 2];
                        fakevalue[0, 0] = 12; fakevalue[0, 1] = 23.2;
                        fakevalue[1, 0] = 21; fakevalue[1, 1] = 29.1;
                        fakevalue[2, 0] = 10; fakevalue[2, 1] = 18.1;
                        fakevalue[3, 0] = 11; fakevalue[3, 1] = 20.6;
                        fakevalue[4, 0] = 25; fakevalue[4, 1] = 34.5;
                          */
                        //read x1,x2,y from dynamic array
                            string create ="CREATE TABLE IF NOT EXISTS Main(Model VARCHAR(50), Alpha decimal , Baseline decimal)";
                            runquery(create);


                        RectangularMatrix x1 = new RectangularMatrix(nvalues, 2);
                        ColumnVector y = new ColumnVector(nvalues);
                        for (int i = 0; i < nvalues; i++)
                        {
                        //value[i,0]=CPU utilization. value[i,1]= Power from meter
                        x1[i, 0] = values[i, 0];
                        x1[i, 1] = 1;
                        y[i, 0] = values[i, 1];
                        }

                        //calculate coefficients
                        ColumnVector coeff = Regressioncalc(x1, x1, y);
                        Console.WriteLine(modelname);
                        //save coefficients to database
                        string coefstoreqry = "INSERT INTO Main(Model, Alpha, Baseline) VALUES ('" + modelname + "' , '" + coeff[0, 0] + "' , '" + coeff[1, 0] + "')";
                        runquery(coefstoreqry);

                        }
                        static ColumnVector Regressioncalc(RectangularMatrix x1, RectangularMatrix x2, ColumnVector y)
                        {
                        /*
                        RectangularMatrix xmat = new RectangularMatrix(5, 2);
                        xmat[0,0] = 12; xmat[0,1] = 1;
                        xmat[1,0] = 21; xmat[1,1] = 1;
                        xmat[2,0] = 10; xmat[2,1] = 1;
                        xmat[3,0] = 11; xmat[3,1] = 1;
                        xmat[4,0] = 25; xmat[4,1] = 1;

                        RectangularMatrix xmat2 = new RectangularMatrix(5, 2);
                        xmat2[0, 0] = 12; xmat2[0, 1] = 1;
                        xmat2[1, 0] = 21; xmat2[1, 1] = 1;
                        xmat2[2, 0] = 10; xmat2[2, 1] = 1;
                        xmat2[3, 0] = 11; xmat2[3, 1] = 1;
                        xmat2[4, 0] = 25; xmat2[4, 1] = 1;

                        ColumnVector ymat = new ColumnVector(5);
                        ymat[0, 0] = 23.2; ymat[1, 0] = 29.1; ymat[2, 0] = 18.1; ymat[3, 0] = 20.6; ymat[4, 0] = 34.5;
                        */
                        //step 1: ATranspose
                        // xmat = xmat.Transpose();
                        x1 = x1.Transpose();
                        //step 2: AT*A;``
                        //xmat = xmat*xmat2;
                        x1 = x1 * x2;
                        //step 3: inverse(AT*A)


                        SquareMatrix xmats = new SquareMatrix(x1.ColumnCount);
                        for (int i = 0; i < x1.RowCount; i++)
                        {
                        for (int j = 0; j < x1.ColumnCount; j++)
                        {
                        xmats[i, j] = x1[i, j];
                        }
                        }
                        xmats = xmats.Inverse();
                        //step 4: AT*y;
                        x2 = x2.Transpose();
                        y = x2 * y;
                        //step 5: multiply step 3 and step 4
                        y = xmats * y;


                        for (int row = 0; row < y.RowCount; row++)
                        {
                        y[row, 0] = Math.Round(y[row, 0], 3);
                        }
                        return y;
                        }

                        }


  
}
